package Rangel.firebrigade.buildingdetector.explore;

import javolution.util.FastSet;
import Rangel.firebrigade.buildingdetector.FireBrigadeTarget;
import Rangel.common.world.helper.RangelWorldHelper;
import Rangel.common.world.entity.RangelBuilding;
import rescuecore2.standard.entities.Area;
import rescuecore2.standard.entities.StandardEntity;
import rescuecore2.worldmodel.EntityID;
import java.util.HashSet;
import java.util.Set;

public class ExploreAroundFireDecisionFactory {
    protected RangelWorldHelper world;
    public ExploreAroundFireDecisionFactory(RangelWorldHelper world) {
        this.world = (world);
        maximalCovering = new MaximalCovering(world);
    }

    private MaximalCovering maximalCovering;
    private FireBrigadeTarget fireBrigadeTarget;
    private Set<EntityID> exploreTargets;
    private EntityID target;

    public void update() {
        exploreTargets.remove(world.getSelfPosition().getID());
        if (world.getSelfPosition().getID().equals(target)) {
            target = null;
        }
    }

    public void setTargetFire(FireBrigadeTarget fireBrigadeTarget, boolean exploreAll) {
        this.fireBrigadeTarget = fireBrigadeTarget;
        fillExplorePlaces(exploreAll);
    }

    private void fillExplorePlaces(boolean exploreAll) {
        Set<RangelBuilding> borderBuildings = new FastSet<>();
        Set<RangelBuilding> allBuildings = new FastSet<>();

        borderBuildings.add(fireBrigadeTarget.getRangelBuilding());
        allBuildings.add(fireBrigadeTarget.getRangelBuilding());

        if (exploreAll) {
            Set<StandardEntity> entitySet = new FastSet<>(fireBrigadeTarget.getCluster().getBorderEntities());
            entitySet.removeAll(fireBrigadeTarget.getCluster().getIgnoredBorderEntities());

            for (StandardEntity entity : entitySet) {
                borderBuildings.add(world.getRangelBuilding(entity.getID()));
                allBuildings.add(world.getRangelBuilding(entity.getID()));
            }
        }
        for (RangelBuilding neighbour : borderBuildings) {
            for (RangelBuilding b : neighbour.getConnectedBuilding()) {

                if (world.getDistance(b.getSelfBuilding(), neighbour.getSelfBuilding()) < world.getViewDistance()) {
                    allBuildings.add(b);
                }
            }
        }

        exploreTargets = maximalCovering.findMaximalCovering(allBuildings);
        target = null;
    }

    public void removeUnreachableArea(EntityID areaId) {
        exploreTargets.remove(areaId);
        target = null;
    }

    public void initialize() {
        exploreTargets = new HashSet<>();
        update();
    }

    public Area getNextArea() {
        if (exploreTargets != null) {
            update();
            if (target == null) {
                int distance;
                int minDistance = Integer.MAX_VALUE;
                for (EntityID areaId : exploreTargets) {
                    distance = world.getDistance(world.getAgentInfo().getID(), areaId);
                    if (distance < minDistance) {
                        minDistance = distance;
                        target = areaId;
                    }
                }
            }
        }
        if (target != null) {
            return (Area) world.getEntity(target);
        }
        return null;
    }
}
